package com.example.lightble;


import java.util.ArrayList;
import java.util.Calendar;
import java.util.Random;

import android.util.Log;


public class CmdSend {

	private static CmdSend  mInstance;
	byte[] CRC_TABLE={
		  0x00,0x5E,(byte) 0xBC,(byte) 0xE2,0x61,0x3F,(byte) 0xDD,(byte) 0x83,(byte) 0xC2,(byte) 0x9C,0x7E,0x20,(byte) 0xA3,(byte) 0xFD,0x1F,0x41,
		  (byte) 0x9D,(byte) 0xC3,0x21,0x7F,(byte) 0xFC,(byte) 0xA2,0x40,0x1E,0x5F,0x01,(byte) 0xE3,(byte) 0xBD,0x3E,0x60,(byte) 0x82,(byte) 0xDC,
		  0x23,0x07,(byte) 0x9F,(byte) 0xC1,0x42,0x1C,(byte) 0xFE,(byte) 0xA0,(byte) 0xE1,(byte) 0xBF,0x5D,0x03,(byte) 0x80,(byte) 0xDE,0x3C,0x62,
		  (byte) 0xBE,(byte) 0xE0,0x02,0x5C,(byte) 0xDF,(byte) 0x81,0x63,0x3D,0x7C,0x22,(byte) 0xC0,(byte) 0x9E,0x1D,0x43,(byte) 0xA1,(byte) 0xFF,
		  0x46,0x18,(byte) 0xFA,(byte) 0xA4,0x27,0x79,(byte) 0x9B,(byte) 0xC5,(byte) 0x84,(byte) 0xDA,0x38,0x66,(byte) 0xE5,(byte) 0xBB,0x59,0x07,
		  (byte) 0xDB,(byte) 0x85,0x67,0x39,(byte) 0xBA,(byte) 0xE4,0x06,0x58,0x19,0x47,(byte) 0xA5,(byte) 0xFB,0x78,0x26,(byte) 0xC4,(byte) 0x9A,
		  0x65,0x3B,(byte) 0xD9,(byte) 0x87,0x04,0x5A,(byte) 0xB8,(byte) 0xE6,(byte) 0xA7,(byte) 0xF9,0x1B,0x45,(byte) 0xC6,(byte) 0x98,0x7A,0x24,
		  (byte) 0xF8,(byte) 0xA6,0x44,0x1A,(byte) 0x99,(byte) 0xC7,0x25,0x7B,0x3A,0x64,(byte) 0x86,(byte) 0xD8,0x5B,0x05,(byte) 0xE7,(byte) 0xB9,
		  (byte) 0x8C,(byte) 0xD2,0x30,0x6E,(byte) 0xED,(byte) 0xB3,0x51,0x0F,0x4E,0x10,(byte) 0xF2,(byte) 0xAC,0x2F,0x71,(byte) 0x93,(byte) 0xCD,
		  0x11,0x4F,(byte) 0xAD,(byte) 0xF3,0x70,0x2E,(byte) 0xCC,(byte) 0x92,(byte) 0xD3,(byte) 0x8D,0x6F,0x31,(byte) 0xB2,(byte) 0xEC,0x0E,0x50,
		  (byte) 0xAF,(byte) 0xF1,0x13,0x4D,(byte) 0xCE,(byte) 0x90,0x72,0x2C,0x6D,0x33,(byte) 0xD1,(byte) 0x8F,0x0C,0x52,(byte) 0xB0,(byte) 0xEE,
		  0x32,0x6C,(byte) 0x8E,(byte) 0xD0,0x53,0x0D,(byte) 0xEF,(byte) 0xB1,(byte) 0xF0,(byte) 0xAE,0x4C,0x12,(byte) 0x91,(byte) 0xCF,0x2D,0x73,
		  (byte) 0xCA,(byte) 0x94,0x76,0x28,(byte) 0xAB,(byte) 0xF5,0x17,0x49,0x08,0x56,(byte) 0xB4,(byte) 0xEA,0x69,0x37,(byte) 0xD5,(byte) 0x8B,
		  0x57,0x09,(byte) 0xEB,(byte) 0xB5,0x36,0x68,(byte) 0x8A,(byte) 0xD4,(byte) 0x95,(byte) 0xCB,0x29,0x77,(byte) 0xF4,(byte) 0xAA,0x48,0x16,
		  (byte) 0xE9,(byte) 0xB7,0x55,0x0B,(byte) 0x88,(byte) 0xD6,0x34,0x6A,0x2B,0x75,(byte) 0x97,(byte) (byte) 0xC9,0x4A,0x14,(byte) 0xF6,(byte) 0xA8,
		  0x74,0x2A,(byte) 0xC8,(byte) 0x96,0x15,0x4B,(byte) 0xA9,(byte) 0xF7,(byte) 0xB6,(byte) 0xE8,0x0A,0x54,(byte) 0xD7,(byte) 0x89,0x6B,0x35
		};
	
	public synchronized static CmdSend  getInstance()
	{
		if(mInstance==null){
			mInstance=new CmdSend();
		}
		return mInstance;
	}
	public void printCmdData(String hint,byte[] array)
	{
		String printStr="";
		if(hint!=null){
			printStr=hint;
			printStr+=":";
		}
		for(int i=0;i<array.length;i++)
		{
			 int v = array[i] & 0xFF;
			 printStr+= Integer.toHexString(v);
			 printStr+=" ";
		}
		Log.i("sno",printStr);
		
	}
    public static byte[] int2Byte(int intValue) {  
        byte[] b = new byte[4];  
        for (int i = 0; i < 4; i++) {  
            b[i] = (byte) (intValue >> 8 * (3 - i) & 0xFF);  
        }  
        return b;  
    }  
	public byte[] getRGBCmdArray(int colorA,int colorB)
	{
		byte crc=0;
		int len=6+8;  //RGB是3+3种颜色
		byte[]  byteArray=new byte[len];
		byteArray[0]=CmdConstants.CMDHEAD1;
		byteArray[1]=CmdConstants.CMDHEAD2;
		byteArray[2]=0x01;  
		byteArray[3]=CmdConstants.CMD_APP_BYTE;
		byteArray[4]=CmdConstants.CMD_WORD_V;
		byteArray[5]=getRandom();  //<---随机数
		byteArray[6]=6;
		
		byte R,G,B;
		R=(byte)(colorA>>16);
		G=(byte)(colorA>>8);
		B=(byte)(colorA);
		
		byteArray[7]=(byte) (R&0xFF);
		byteArray[8]=(byte) (G&0xFF);
		byteArray[9]=(byte) (B&0xFF);
		
		R=(byte)(colorB>>16);
		G=(byte)(colorB>>8);
		B=(byte)(colorB);
		byteArray[10]=(byte) (R&0xFF);
		byteArray[11]=(byte) (G&0xFF);
		byteArray[12]=(byte) (B&0xFF);
	
		EncryptCode(byteArray);  //加密数据.
		for(int i=0;i<len-1;i++)
		{
			 crc ^=byteArray[i];
			 int index=(int)(crc&0xff);
			 crc=CRC_TABLE[index];
		}
		byteArray[len-1]=crc;
		return byteArray;
	}
	
	public byte[] getMoreRGBArray(ArrayList<Integer> colorList)
	{
		byte crc=0;
		if(colorList.isEmpty() ||colorList.size()>10)
			return null;

		int listsize=colorList.size();
		
		int len=listsize*3+8;
		byte[]  byteArray=new byte[len];
		byteArray[0]=CmdConstants.CMDHEAD1;
		byteArray[1]=CmdConstants.CMDHEAD2;
		byteArray[2]=0x01;  
		byteArray[3]=CmdConstants.CMD_APP_BYTE;
		byteArray[4]=CmdConstants.CMD_WORD_C;
		byteArray[5]=getRandom();  //<---随机数
		byteArray[6]=(byte) (listsize*3);
		
		byte R,G,B;
		int index=7;
		for(int color: colorList)
		{
			
			R=(byte)(color>>16);
			G=(byte)(color>>8);
			B=(byte)(color);
			
			byteArray[index++]=(byte) (R&0xFF);
			byteArray[index++]=(byte) (G&0xFF);
			byteArray[index++]=(byte) (B&0xFF);
		}
		
		EncryptCode(byteArray);
		for(int i=0;i<len-1;i++)
		{
			 crc ^=byteArray[i];
			 int tmp=(int)(crc&0xff);
			 crc=CRC_TABLE[tmp];
		}
		byteArray[len-1]=crc;
		return byteArray;
	}
	
	/*
	 * S命令字（STORAGE）：数据0字节，数据长度0
*/
	public byte[] getStoreCmdArray()  //
	{
		byte crc=0;
		int len=CmdConstants.CMD_S_LENGTH+8;
		byte[]  byteArray=new byte[len];
		
		
		byteArray[0]=CmdConstants.CMDHEAD1;
		byteArray[1]=CmdConstants.CMDHEAD2;
		byteArray[2]=0x01;  
		byteArray[3]=CmdConstants.CMD_APP_BYTE;
		byteArray[4]=CmdConstants.CMD_WORD_S;
		byteArray[5]=getRandom();  //<---随机数
		byteArray[6]=CmdConstants.CMD_S_LENGTH;

		EncryptCode(byteArray);
		for(int i=0;i<len-1;i++)
		{
			crc ^=byteArray[i];
			 int index=(int)(crc&0xff);
			crc=CRC_TABLE[index];
		}
		byteArray[len-1]=crc;
		printCmdData("getStoreCmdArray", byteArray);
		return byteArray;
	}
	
	/*
		D命令字（DEFAULT）：数据0字节，数据长度0
*/
	public byte[] getDefaultCmdArray()
	{
		byte crc=0;
		int len=CmdConstants.CMD_D_LENGTH+8;
		byte[]  byteArray=new byte[len];
		byteArray[0]=CmdConstants.CMDHEAD1;
		byteArray[1]=CmdConstants.CMDHEAD2;
		byteArray[2]=0x01;  
		byteArray[3]=CmdConstants.CMD_APP_BYTE;
		byteArray[4]=CmdConstants.CMD_WORD_D;
		byteArray[5]=getRandom();  //<---随机数
		byteArray[6]=CmdConstants.CMD_D_LENGTH;

		EncryptCode(byteArray);
		for(int i=0;i<len-1;i++)
		{
			crc ^=byteArray[i];
			 int index=(int)(crc&0xff);
			crc=CRC_TABLE[index];
		}
		byteArray[len-1]=crc;
		printCmdData("getDefaultCmdArray", byteArray);
		return byteArray;
	}
	public byte[] getNameCmdArray(byte[] name)
	{
		if(name.length<=0)
		{
			Log.e("sno","sendName error =null");
			return null;
		}
		byte crc=0;
		int len=name.length+8;
		byte[]  byteArray=new byte[len];
		
		byteArray[0]=CmdConstants.CMDHEAD1;
		byteArray[1]=CmdConstants.CMDHEAD2;
		byteArray[2]=0x01;  //协议版本
		byteArray[3]=CmdConstants.CMD_APP_BYTE;
		byteArray[4]=CmdConstants.CMD_WORD_N;
		byteArray[5]=getRandom();  //<---随机数
		byteArray[6]=(byte) name.length;
		
		
		for(int i=0;i<name.length;i++)
		{
			byteArray[7+i]=name[i];
		}

		EncryptCode(byteArray);
		for(int i=0;i<len-1;i++)
		{
			crc ^=byteArray[i];
			 int index=(int)(crc&0xff);
			crc=CRC_TABLE[index];
		}
		byteArray[len-1]=crc;
		return byteArray;
	}
	
	/*
		P命令字（PASSWORD）：
*/
	public byte[] getPassWdCmdArray(String passwd)
	{
		byte crc=0;
		if(passwd==null){
			Log.e("sno","getPassWdCmdArray passwd==null");
			return null;
		}
		int len;
		if(passwd.length()>6){
			len=6+8;
		}else{
			len=passwd.length()+8;
		}
		byte[]  byteArray=new byte[len];
		byteArray[0]=CmdConstants.CMDHEAD1;
		byteArray[1]=CmdConstants.CMDHEAD2;
		byteArray[2]=0x01;  
		byteArray[3]=CmdConstants.CMD_APP_BYTE;
		byteArray[4]=CmdConstants.CMD_WORD_P;
		byteArray[5]=getRandom();  //<---随机数
		byteArray[6]=(byte) passwd.length();
		
		byte[] strArray=passwd.getBytes();
		for(int i=0;i<len-8;i++)
		{
			byteArray[7+i]=strArray[i];
		}
		
		EncryptCode(byteArray);
		for(int i=0;i<len-1;i++)
		{
			crc ^=byteArray[i];
			 int index=(int)(crc&0xff);
			crc=CRC_TABLE[index];
		}
		byteArray[len-1]=crc;
		return byteArray;
	}
	/**
	 * 这个是绑定密码, 每次连上后, 立即发送这条命令.
	 * @param passwd
	 * @return
	 */
	public byte[] getBondPassWdArray(String passwd)
	{
		byte crc=0;
		if(passwd==null){
			Log.i("sno","passwd-------==null");
			return null;
		}
		int len;
		if(passwd.length()>6){
			len=6+8;
		}else{
			len=passwd.length()+8;
		}
		byte[]  byteArray=new byte[len];
		byteArray[0]=CmdConstants.CMDHEAD1;
		byteArray[1]=CmdConstants.CMDHEAD2;
		byteArray[2]=0x01;  
		byteArray[3]=CmdConstants.CMD_APP_BYTE;
		byteArray[4]=CmdConstants.CMD_WORD_T;
		byteArray[5]=getRandom();  //<---随机数
		byteArray[6]=(byte) passwd.length();
		
		byte[] strArray=passwd.getBytes();
		for(int i=0;i<len-8;i++)
		{
			byteArray[7+i]=strArray[i];
		}
		
		EncryptCode(byteArray);
		for(int i=0;i<len-1;i++)
		{
			crc ^=byteArray[i];
			 int index=(int)(crc&0xff);
			crc=CRC_TABLE[index];
		}
		byteArray[len-1]=crc;
		return byteArray;
	}
	/*
	  F命令, 自由变换色
 */
	public byte[] getTiaoBianArray(boolean enable,byte second)  //flash是2个字节, enable是否使能, second,使能后闪烁间隔的秒数.
	{
		byte crc=0;
		
		int len=2+8;  ///2表示flash是2个字节
		byte[]  byteArray=new byte[len];
		byteArray[0]=CmdConstants.CMDHEAD1;
		byteArray[1]=CmdConstants.CMDHEAD2;
		byteArray[2]=0x01;  
		byteArray[3]=CmdConstants.CMD_APP_BYTE;
		byteArray[4]=CmdConstants.CMD_WORD_F;
		byteArray[5]=getRandom();  //<---随机数
		
		byteArray[6]=2;  //flash的字节长度是2
		
		byteArray[7]=(byte) (enable?0xFF:0x00);
		byteArray[8]=second;
		

		EncryptCode(byteArray);
		for(int i=0;i<len-1;i++)
		{
			crc ^=byteArray[i];
			 int index=(int)(crc&0xff);
			crc=CRC_TABLE[index];
		}
		byteArray[len-1]=crc;
		printCmdData("getScheduleTimeArray", byteArray);
		return byteArray;
	}
	/*
	 自由渐变颜色
*/
	public byte[] getJianBianArray(boolean enable,byte second) 
	{
		byte crc=0;
		
		int len=2+8;  
		byte[]  byteArray=new byte[len];
		byteArray[0]=CmdConstants.CMDHEAD1;
		byteArray[1]=CmdConstants.CMDHEAD2;
		byteArray[2]=0x01;  
		byteArray[3]=CmdConstants.CMD_APP_BYTE;
		byteArray[4]=CmdConstants.CMD_WORD_S;
		byteArray[5]=getRandom();  //<---随机数
		
		byteArray[6]=2;  //flash的字节长度是2
		
		byteArray[7]=(byte) (enable?0xFF:0x00);
		byteArray[8]=second;
		

		EncryptCode(byteArray);
		for(int i=0;i<len-1;i++)
		{
			crc ^=byteArray[i];
			 int index=(int)(crc&0xff);
			crc=CRC_TABLE[index];
		}
		byteArray[len-1]=crc;
		return byteArray;
	}
	/*
	 开关灯
*/
	public byte[] getOpenLightArray(boolean isOpen) 
	{
		byte crc=0;
		int len=1+8;  //<----数据长度为1.  
		byte[]  byteArray=new byte[len];
		byteArray[0]=CmdConstants.CMDHEAD1;
		byteArray[1]=CmdConstants.CMDHEAD2;
		byteArray[2]=0x01;  
		byteArray[3]=CmdConstants.CMD_APP_BYTE;
		byteArray[4]=CmdConstants.CMD_WORD_O;
		byteArray[5]=getRandom();  //<---随机数
		
		byteArray[6]=1;  //开灯是一个字节.
		byteArray[7]=(byte) (isOpen?0x01:0x00);

		EncryptCode(byteArray);
		for(int i=0;i<len-1;i++)
		{
			crc ^=byteArray[i];
			 int index=(int)(crc&0xff);
			crc=CRC_TABLE[index];
		}
		byteArray[len-1]=crc;
		return byteArray;
	}
	/**
	 * 一键设置为白光
	 * @return
	 */
	public byte[] getOneKeyWhiteArray() 
	{
		byte crc=0;
		int len=8+8;  //<----数据长度为8.  
		byte[]  byteArray=new byte[len];
		byteArray[0]=CmdConstants.CMDHEAD1;
		byteArray[1]=CmdConstants.CMDHEAD2;
		byteArray[2]=0x01;  
		byteArray[3]=CmdConstants.CMD_APP_BYTE;
		byteArray[4]=CmdConstants.CMD_WORD_W;
		byteArray[5]=getRandom();  //<---随机数
		
		byteArray[6]=8;  //RA GA BA RB GB BB WA WB （8字节数据全是0xFF）
		
		byteArray[7]=(byte) 0xFF;
		byteArray[8]=(byte) 0xFF;
		byteArray[9]=(byte) 0xFF;
		byteArray[10]=(byte) 0xFF;
		byteArray[11]=(byte) 0xFF;
		byteArray[12]=(byte) 0xFF;
		byteArray[13]=(byte) 0xFF;
		byteArray[14]=(byte) 0xFF;

		EncryptCode(byteArray);
		for(int i=0;i<len-1;i++)
		{
			crc ^=byteArray[i];
			 int index=(int)(crc&0xff);
			crc=CRC_TABLE[index];
		}
		byteArray[len-1]=crc;
		return byteArray;
	}
	
	/**
	 * 
	 * @param  
	 * @return
	 */
	public byte[] getSyncBianArray() 
	{
		byte crc=0;
		int len=1+8;  //<----数据长度为1.  
		byte[]  byteArray=new byte[len];
		byteArray[0]=CmdConstants.CMDHEAD1;
		byteArray[1]=CmdConstants.CMDHEAD2;
		byteArray[2]=0x01;  
		byteArray[3]=CmdConstants.CMD_APP_BYTE;
		byteArray[4]=CmdConstants.CMD_WORD_A;
		byteArray[5]=getRandom();  //<---随机数
		
		byteArray[6]=1;  //同步一个字节
		byteArray[7]=0x01;  //同步数据为真.

		EncryptCode(byteArray);
		for(int i=0;i<len-1;i++)
		{
			crc ^=byteArray[i];
			 int index=(int)(crc&0xff);
			crc=CRC_TABLE[index];
		}
		byteArray[len-1]=crc;
		Log.i("sno","发送同步命令.....");
		return byteArray;
	}
	
	public void EncryptCode(byte[] Data)
	{
		byte RandomNum=Data[5];
		int len=(byte)Data[6];
		int  i;
		//协议从第七个字节开始加密
		for(i=0;i<len;i++)
		{
			Data[7+i] ^=RandomNum;
			Data[7+i] ^=CRC_TABLE[len];
		}
	}
	public void DecryptCode(byte[] Data)
	{
		byte RandomNum=Data[5];		
		int len=(byte)Data[6];
		int  i;
		//协议从第七个字节开始加密
		for(i=0;i<len;i++)
		{
			Data[7+i] ^=RandomNum;
			Data[7+i] ^=CRC_TABLE[len];
		}
	}
	public  byte getRandom()
	{
		int min=1;  //可以设置最大值和最小值
		int max=255;
		Random random = new Random();
		int s = random.nextInt(max) % (max - min + 1) + min;
		return (byte)s;
	}
	public boolean checkRcvData(byte[] byteArray)
	{
		int datalen=0;
		int pkglen;
		byte crc=0;
		pkglen=byteArray.length;
		
		if(pkglen>=7)
		{
			datalen=byteArray[6];
			
			if(pkglen==(datalen+8))  //数据长度是正确的.
			{
				for(int i=0;i<pkglen-1;i++)
				{
					 crc ^=byteArray[i];
					 int index=(int)(crc&0xff);
					 crc=CRC_TABLE[index];
				}
				if( crc == byteArray[pkglen-1])
					return true;
				else{
					Log.e("sno","checkRcvData: crc check sum rror!");
					return false;
				}
			}else{
				Log.e("sno","checkRcvData: pkglen!=datalen+protocollen,error!");
				return false;
			}
		}else{
			Log.e("sno","checkRcvData: pkglen<7,error!");
			return false;
		}
	}
}
